home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_45 / wav.c < prev    next >
C/C++ Source or Header  |  1995-01-01  |  7KB  |  196 lines

  1. /* BEGIN DAVID LAI COPYRIGHT ********************************************* */
  2. /*
  3. (C) Copyright David Lai 1993, 1994.  All rights reserved.
  4.  
  5. The source code is copyright by David Lai, however it is freely
  6. distributable and released for unrestricted use.  Users may copy or modify 
  7. this source code without charge, provided all copyright
  8. notices remain intact in all the source code.  Portions of the source code
  9. copyright by their respective copyright holders and are covered
  10. under different agreements, however the source code used has
  11. specifically been marked distributable royalty-free.
  12.  
  13. You can do whatever you want with it, even charge money for it, if
  14. you find a sucker willing to pay for it.  This is not shareware, the program
  15. is not crippled in any way, do not send money.  You can e-mail comments
  16. to the electronic mail address below, or fax to the fax number below.
  17.  
  18. If you add a feature thats useful, or do a new port, you can send
  19. the context diffs to the e-mail address below.  I may include it in
  20. subsequent releases.  Your code must specifically be marked
  21. freely distributable, I will not include code marked otherwise.
  22.  
  23. THE SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
  24. THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  25. PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  26.  
  27. The source code is provided with no support and without any obligation on
  28. the part of David Lai to assist in its use, correction,
  29. modification or enhancement.
  30.  
  31. DAVID LAI SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  32. INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
  33. OR ANY PART THEREOF.
  34.  
  35. In no event will David Lai be liable for any lost revenue
  36. or profits or other special, indirect and consequential damages, even if
  37. David Lai has been advised of the possibility of such damages.
  38.  
  39. David Lai
  40. 1370 McKendrie St
  41. San Jose, CA 95126
  42. fax: 408-241-4615
  43.  
  44. lai%fastfood@daver.bungi.com
  45.  
  46. */
  47. /* END   DAVID LAI COPYRIGHT ********************************************* */
  48.  
  49. /* wave file I/O */
  50.  
  51. #include "misc.h"
  52. #include "modcomp.h"
  53. #include "wav.h"
  54.  
  55. #ifdef __STDC__
  56. FILE * wav_write( signed char *sample_data, struct sample *sample_info,
  57.         uint32 sample_rate, int info_flag)
  58. #else
  59. FILE * wav_write( sample_data, sample_info, sample_rate, info_flag)
  60.  signed char *sample_data; struct sample *sample_info; uint32 sample_rate;
  61.  int info_flag;
  62. #endif
  63.  {
  64.  /* write the sample as a .wav file */
  65.  /* In Microsoft syntax: 
  66.     RIFF ( 'WAVE'
  67.            fmt(1, 1, sample_rate, sample_rate, 1, 8)
  68.            data (sample_data) 
  69.            INFO( INAM(sample_name) ISFT("Wave Compiler v. nn.n"Z)
  70.              ICMT("Volume: vv Finetune: ff RepeatOffset: ooo RepeatLength: lll"Z))
  71.         )
  72.         
  73.         The INFO chunk is optional
  74.  
  75.     Note: The default sample rate is 16574Hz, the sample rate of a C-3
  76.           period, which is the
  77.           de-facto standard sampling rate for mod samples.  However
  78.           some systems may have problems playing at this rate.  In
  79.           these situations you may want to convert to a more
  80.           standard rate, like 11025, you can specify a command line
  81.           option, or use sox, or some other conversion package.
  82.  
  83.           sample_data will be written in 8-bit unsigned format.
  84.  */
  85.  FILE *fw;
  86.  uint32 wave_size, isiz, dsiz, fsiz, chunk_header_siz;
  87.  uint32 inam_siz, isft_siz, icmt_siz, list_header_siz, riff_header_siz, info_size;
  88.  char comment[100];
  89.  PCMWAVEFORMAT fmt;
  90.  if (sample_info->sample_filename ==NULL)
  91.     err_exit("No filename specified for .wav write", NULL);
  92.  if ((fw = fopen(sample_info->sample_filename, WRITEBINARY))==NULL)
  93.     err_exit("Cant create %s", sample_info->sample_filename);
  94.  /* calculate the sizes of the various chunks */
  95.  /* common chunk header size */
  96.  chunk_header_siz = 8;
  97.  list_header_siz = chunk_header_siz + 4; /* standard header + list type */
  98.  riff_header_siz = chunk_header_siz + 4; /* standard header + form type */
  99.  
  100.  /* data, fmt, and riff chunks are always required - info optional */
  101.  /* wave data */
  102.  dsiz = (unsigned long)sample_info->length * 2 - 2;
  103.  /* fmt */
  104.  fsiz = sizeof(PCMWAVEFORMAT);
  105. if (info_flag) 
  106.  {
  107.  /* info */
  108.  inam_siz = (strlen(sample_info-> name)+1);
  109.  isft_siz = (strlen(PRODUCT_ID)+1);
  110.  sprintf(comment,"Volume: %d Finetune: %d RepeatOffset: %u RepeatLength: %u", sample_info->volume, sample_info-> finetune, sample_info->rpt_offset, sample_info->rpt_length);
  111.  icmt_siz = (strlen(comment)+1);
  112.  isiz = EVEN(inam_siz) + EVEN(isft_siz)  + EVEN(icmt_siz) + 3 * chunk_header_siz;
  113.  info_size = isiz + list_header_siz;
  114.  }
  115. else
  116.  {
  117.  info_size = 0;
  118.  }
  119.  wave_size = info_size + EVEN(dsiz) + EVEN(fsiz) + 2 * chunk_header_siz + riff_header_siz;
  120.  
  121.  /* now write the file */
  122.  wllong(fw, cc4_RIFF);    /* RIFF (WAVE */
  123.  wllong(fw, wave_size-chunk_header_siz); /* size doesn't include standard header */
  124.  wllong(fw,cc4_WAVE);
  125.  fmt.wFormatTag = WAVE_FORMAT_PCM;
  126.  fmt.nChannels = 1;
  127.  fmt.nSamplesPerSec = sample_rate;
  128.  fmt.wBitsPerSample = 8;
  129.  fmt.nBlockAlign = fmt.nChannels * ((fmt.wBitsPerSample+7) / 8 );
  130.  fmt.nAvgBytesPerSec = fmt.nChannels * ((fmt.wBitsPerSample+7) / 8) * sample_rate;
  131.  wllong(fw, cc4_fmt);    /* fmt(1, 1, sample_rate, sample_rate, 1, 8) */
  132.  wllong(fw,fsiz);
  133.  wlshort(fw,fmt.wFormatTag);
  134.  wlshort(fw,fmt.nChannels);
  135.  wllong(fw,fmt.nSamplesPerSec);
  136.  wllong(fw,fmt.nAvgBytesPerSec);
  137.  wlshort(fw,fmt.nBlockAlign);
  138.  wlshort(fw,fmt.wBitsPerSample);
  139.  wllong(fw, cc4_data);    /* data (sample_data)) */
  140.  wllong(fw, dsiz);
  141.  
  142.  /* the data is in memory or in the file at the indicated offset */
  143.  /* we defer writes to the write_continue */
  144.  return fw;
  145.  }
  146.  
  147. #ifdef __STDC__
  148. void wav_write_final( FILE *fw, struct sample *sample_info,
  149.         uint32 sample_rate, int info_flag)
  150. #else
  151. void wav_write_final( fw, sample_info, sample_rate, info_flag)
  152.  FILE * fw; struct sample *sample_info; uint32 sample_rate;
  153.  int info_flag;
  154. #endif
  155.  {
  156.  /* finish writing the sample as a .wav file */
  157.  /* in our case we write the INFO list if requested */
  158.  uint32 isiz, chunk_header_siz;
  159.  uint32 inam_siz, isft_siz, icmt_siz, list_header_siz, info_size;
  160.  char comment[100];
  161.  chunk_header_siz = 8;
  162.  list_header_siz = chunk_header_siz + 4; /* standard header + list type */
  163. if (info_flag) 
  164.   {
  165.   /* info */
  166.   inam_siz = (strlen(sample_info-> name)+1);
  167.   isft_siz = (strlen(PRODUCT_ID)+1);
  168.   sprintf(comment,"Volume: %d Finetune: %d RepeatOffset: %u RepeatLength: %u", sample_info->volume, sample_info-> finetune, sample_info->rpt_offset, sample_info->rpt_length);
  169.   icmt_siz = (strlen(comment)+1);
  170.   isiz = EVEN(inam_siz) + EVEN(isft_siz)  + EVEN(icmt_siz) + 3 * chunk_header_siz;
  171.   info_size = isiz + list_header_siz;
  172.   wllong(fw, cc4_LIST);    /* LIST INFO ( */
  173.   wllong(fw, info_size - chunk_header_siz);
  174.   wllong(fw, cc4_INFO);
  175.   wllong(fw, cc4_INAM);    /* INAM(sample_name) */
  176.   wllong(fw, inam_siz);
  177.   wezstr(fw, sample_info-> name);
  178.   wllong(fw, cc4_ISFT);    /* ISFT("Wave Compiler v. nn.n"Z) */
  179.   wllong(fw, isft_siz);
  180.   wezstr(fw, PRODUCT_ID);
  181.   wllong(fw, cc4_ICMT);    /* ICMT("Volume: vv Finetune: ff RepeatOffset: ooo RepeatLength: lll"Z)) */
  182.   wllong(fw, icmt_siz);
  183.   wezstr(fw, comment);
  184.   }
  185.  }
  186.  
  187. static char rcs_id[]="$Id: wav.c,v 1.1 1994/03/19 09:21:31 dlai Exp $";
  188.  
  189. #if 0
  190. $Log: wav.c,v $
  191.  * Revision 1.1  1994/03/19  09:21:31  dlai
  192.  * Initial revision
  193.  *
  194.  
  195. #endif
  196.